﻿using System;
using System.Collections;
using System.Collections.Generic;
#if TASKSUPPORT
using System.Threading.Tasks;
#endif
using System.Linq.Expressions;
using MugenMvvmToolkit.Interfaces;
using MugenMvvmToolkit.Models;
using MugenMvvmToolkit.Utils;

namespace MugenMvvmToolkit.Infrastructure
{
    /// <summary>
    ///     Represents the simple validator that not has validation logic, user sets all erros.
    /// </summary>
    public class SimpleValidator : ValidatorBase
    {
        #region Methods

        /// <summary>
        ///     Sets errors for a property
        /// </summary>
        /// <typeparam name="T">The type of the model.</typeparam>
        /// <param name="propertyExpresssion">The expression for the property</param>
        /// <param name="errors">The collection of errors</param>
        public void SetErrors<T>(Expression<Func<T, object>> propertyExpresssion, params object[] errors)
        {
            base.SetErrors(MvvmUtilsInternal.ParsePropertyExpression(propertyExpresssion), errors);
        }

        /// <summary>
        ///     Set errors for a property.
        /// </summary>
        /// <param name="propertyName">The name of the property</param>
        /// <param name="errors">The collection of errors</param>
        public new void SetErrors(string propertyName, params object[] errors)
        {
            base.SetErrors(propertyName, errors);
        }

        #endregion

        #region Overrides of ValidatorBase

        /// <summary>
        ///     Indicates that can be only once instance of this validator.
        /// </summary>
        public override bool IsUnique
        {
            get { return false; }
        }

        /// <summary>
        ///     Checks to see whether the validator can validate objects of the specified IValidatorContext.
        /// </summary>
        protected override bool CanValidateInternal(IValidatorContext validatorContext)
        {
            return true;
        }

#if TASKSUPPORT
        /// <summary>
        ///     Updates information about errors in the specified property.
        /// </summary>
        /// <param name="propertyName">The specified property name.</param>        
        /// <returns>
        ///     The result of validation.
        /// </returns>
        protected override Task<IEnumerable> ValidateInternal(string propertyName)
        {
            IEnumerable value;
            InternalErrors.TryGetValue(propertyName, out value);
            if (value == null)
                return EmptyValidateResult;
            return FromResult(value);
        }

        /// <summary>
        ///     Updates information about all errors.
        /// </summary>
        /// <returns>
        ///     The result of validation.
        /// </returns>
        protected override Task<IDictionary<string, IEnumerable>> ValidateAllInternal()
        {
            if (InternalErrors.Count == 0)
                return EmptyValidateAllResult;
            return FromResult<IDictionary<string, IEnumerable>>(InternalErrors);
        }
#else

        /// <summary>
        ///     Updates information about errors in the specified property.
        /// </summary>
        /// <param name="propertyName">The specified property name.</param>
        protected override IOperationResult<IEnumerable> ValidateInternal(string propertyName)
        {
            IEnumerable value;
            InternalErrors.TryGetValue(propertyName, out value);
            if (value == null)
                return EmptyListResult;
            return FromResult(value);
        }

        /// <summary>
        ///     Updates information about all errors.
        /// </summary>        
        protected override IOperationResult<IDictionary<string, IEnumerable>> ValidateAllInternal()
        {
            if (InternalErrors.Count == 0)
                return EmptyDictionaryResult;
            return FromResult<IDictionary<string, IEnumerable>>(InternalErrors);
        }
#endif
        /// <summary>
        ///     Creates a new validator that is a copy of the current instance.
        /// </summary>
        /// <returns>
        ///     A new validator that is a copy of this instance.
        /// </returns>
        protected override IValidator CloneInternal()
        {
            return new SimpleValidator();
        }

        #endregion
    }
}